package com.zhang.queue;

/**
 * 队列可以使用数组和链表实现
 * 循环队列
 */
public class CircleArrayQueueDemo {



  public static void main(String[] arg0)
  {
      CircleArrayQueue2 arrayQueue2=new CircleArrayQueue2(4);
      arrayQueue2.add(1);
      arrayQueue2.add(2);
      arrayQueue2.add(3);
      arrayQueue2.add(4);
      arrayQueue2.show();
      System.out.println(arrayQueue2.get());
      arrayQueue2.add(4);
      System.out.println(arrayQueue2.get());
      arrayQueue2.add(1);
      arrayQueue2.show();
  }

  static class CircleArrayQueue{
      private  int maxSize; //表示数组的容量
      private  int front;   //指向队列头
      private  int rear;   //指向队尾
      private  int[] arr;   //队列数据

      CircleArrayQueue(int size)
      {
          maxSize=size;
          arr=new int[maxSize];
//          front=-1;   //指向队列头,是队列头前一个位置
//          rear=-1;    //指向队尾，指向最后一个数据

      }

      /**
       * 和普通队列不投的是这里判断是否满的条件没有那么单纯了
       * @return
       */
      public  boolean isFull(){

//          return rear==maxSize-1;
          //todo 注意循环队列怎么判断是否满
          return (rear+1) % maxSize == front;
      }

      public boolean isEmpty(){
          return rear==front;
      }

      /**
       * 添加数据
       * @param data
       */
      public  void  addQueue(int data)
      {
          if (isFull())
          {
              System.out.println("队列已满");
              return;
          }
//          rear++;
//          arr[rear]=data;
          arr[rear]=data;
          //todo 注意循环队列怎么自动寻找头尾指针
          rear=(rear+1) % maxSize;
      }

      /**
       * 获取最前端数据
       * @return
       */
      public  int getQueue()
      {
          if (isEmpty())
          {
             throw new RuntimeException("队列为空");
          }
//          front++;
//          return arr[front];
//          这里需要分析出front是指向队列的第一个元素
//          1.先把front对应的值保留到一个临时变量
//          2.将front先后移，考虑取模
//          3.将临时保存的返回
          int value =arr[front];
          //todo 注意怎么寻找队列头
          front=(front+1)% maxSize;
          return value;
      }

      /**
       * 显示队列数据
       */
      public void showQueue()
      {
          if (isEmpty())
          {
              System.out.println("队列暂无数据");
              return;
          }
//          for (int i=0; i<arr.length;i++)
//          {
//              System.out.printf("arr[%d]=%d\n",i,arr[i]);
//          }
          //从front开始遍历，遍历多少个元素
//          需要知道当前有效数据。

            for (int i=front;i<front+size();i++)
            {
              System.out.printf("arr[%d]=%d\n",i%maxSize,arr[i%maxSize]);

            }
//
      }

      /**
       * 求出当前有效的数据个数
       * @return
       * todo 注意循环队列怎么统计当前数据个数
       */
       public  int size()
       {
           return (rear+maxSize-front)%maxSize;
       }


      public  int headQueue()
      {
          if (isEmpty())
          {
            throw new RuntimeException("队列暂无数据");
          }
//          return arr[front+1];
          return arr[front];
      }

  }

    /**
     * 看完视频手写的
     */
  static  class CircleArrayQueue2{

      private  int maxSize;
      private int head;
      private  int foot;
      private int[] arry;

      CircleArrayQueue2(int maxSizes)
      {
          maxSize=maxSizes;
         arry= new int[maxSize];
      }

      public  boolean isFull()
    {
         return   (foot+1) % maxSize == head;
    }
    public  boolean isEmpty()
    {
        return head==foot;
    }
    public  void  add(int data)
    {
        if (isFull())
        {
            System.out.println("数据已满");
            return;
        }
        arry[foot]=data;
        foot=(foot+1) % maxSize;

    }

    public  int get()
    {
        if (isEmpty())
        {
            throw new RuntimeException("队列已空");
        }

        int value= arry[head];
        head=(head+1) % maxSize;
        return value;
    }

    public void show() {
        if (isEmpty()) {
            System.out.println("队列无数据");
            return;
        }
        for (int i = head; i < head + size(); i++)
        {
            System.out.println("a["+(i%maxSize)+"]:"+arry[(i%maxSize)]);
        }
    }

    public int size()
    {
        return (foot+maxSize-head) % maxSize;
    }

  }
}
